<?php
namespace App\Services;

use App\Role;
use App\UserRole;
use App\RoleMenuPermission;
use App\MenuPermission;
use App\PartnerGroupTypePermission;
use App\Lib\Util\QueryPager;
use DB;

class RoleService
{
    private function baseQuery()
    {
        return Role::select('id', 'name', 'description');
    }

    public function getRoles(Array $input, $paging = true)
    {
        $query = $this->baseQuery();

        if (!empty($input['groupId'])) {
            $query = $query->where('group_id', $input['groupId']);
        }

        if (!empty($input['name'])) {
            $query->where('name', 'like' , '%'.$input['name'].'%');
        }

        $pager = new QueryPager($query);

        return $paging ? $pager->doPaginate($input, 'name') :
            $pager->queryWithoutPaginate($input, 'name');
    }

    public function getRolePermissions($roleId)
    {
        return RoleMenuPermission::where('role_id', $roleId)->get()->pluck('permission_id')->toArray();
    }

    public function getGroupMenuPermission($groupTypeId, $level, $spread = true)
    {
        $groupTypePermissionIds = PartnerGroupTypePermission::where('group_type_id', $groupTypeId)->get()
            ->pluck('permission_id')->toArray();

        $topNavi = MenuPermission::select('id', 'name', 'permission_type', 'is_default')
            ->where('permission_type', MenuPermission::$PERMISSION_TYPE_TOP_NAVI)
            ->whereIn('id', $groupTypePermissionIds)
            ->orderBy('sort_order')->get()->toArray();

        $result = [];

        foreach ($topNavi as $topNaviItem) {
            $menuGroups = MenuPermission::select('id', 'name', 'permission_type', 'is_default')
                ->where('permission_type', MenuPermission::$PERMISSION_TYPE_MENU_GROUP)
                ->where('parent_id', $topNaviItem['id'])
                ->whereIn('id', $groupTypePermissionIds)
                ->orderBy('sort_order')->get()->toArray();

            $childrenLevel1 = [];

            if ($level > 1) {
                foreach ($menuGroups as $menuGroup) {
                    $menus = MenuPermission::select('id', 'name', 'permission_type', 'is_default')
                        ->where('permission_type', MenuPermission::$PERMISSION_TYPE_MENU)
                        ->where('parent_id', $menuGroup['id'])
                        ->whereIn('id', $groupTypePermissionIds)
                        ->orderBy('sort_order')->get()->toArray();

                    $childrenLevel2 = [];

                    if ($level > 2) {
                        if ($level > 3) {
                            foreach ($menus as $menu) {
                                $permissions = MenuPermission::select('id', 'name', 'permission_type', 'is_default')
                                    ->where('permission_type', MenuPermission::$PERMISSION_TYPE_OPERATION)
                                    ->where('parent_id', $menu['id'])
                                    ->whereIn('id', $groupTypePermissionIds)
                                    ->orderBy('sort_order')->get()->toArray();

                                array_push($childrenLevel2, array_merge($menu, [
                                    'spread' => $spread,
                                    'children' => $permissions
                                ]));
                            }
                        } else {
                            $childrenLevel2 = $menus;
                        }
                    }

                    array_push($childrenLevel1, array_merge($menuGroup, [
                        'spread' => $spread,
                        'children' => $childrenLevel2
                    ]));
                }
            }

            array_push($result, array_merge($topNaviItem, [
                'spread' => $spread,
                'children' => $childrenLevel1
            ]));
        }

        return $result;
    }

    public function clearOriginalPermissionsByRole($roleId)
    {
        RoleMenuPermission::where('role_id', $roleId)->delete();
    }

    public function saveRolePermissions($roleId, $permissionIds)
    {
        DB::transaction(function () use ($roleId, $permissionIds) {
            $this->clearOriginalPermissionsByRole($roleId);

            foreach ($permissionIds as $permissionId) {
                if (!empty($permissionId)) {
                    RoleMenuPermission::create([
                        'role_id' => $roleId,
                        'permission_id' => $permissionId
                    ]);
                }
            }
        });
    }

    public function deleteRole($roleId)
    {
        DB::transaction(function () use ($roleId) {
            RoleMenuPermission::where('role_id', $roleId)->delete();

            $role = Role::findOrFail($roleId);
            $role->delete();
        });
    }

    public function getGroupRoles($groupId)
    {
        return Role::where('group_id', $groupId)->get();
    }

    public function hasConstrait($roleId)
    {
        return UserRole::where('role_id', $roleId)->count() > 0;
    }

    public function isTheOnlyOneExistsRole($roleId)
    {
        $role = Role::findOrFail($roleId);
        return Role::where('group_id', $role->group_id)->count() <= 1;
    }

    public function isRoleAsDefaultGroupRole($roleId)
    {
        $role = Role::findOrFail($roleId);
        return $role->name == config('system.default_admin_role_name');
    }
}
